function varargout = iCalibrateSubtract(varargin)
% ICALIBRATESUBTRACT M-file for iCalibrateSubtract.fig
%      ICALIBRATESUBTRACT, by itself, creates a new ICALIBRATESUBTRACT or raises the existing
%      singleton*.
%
%      H = ICALIBRATESUBTRACT returns the handle to a new ICALIBRATESUBTRACT or the handle to
%      the existing singleton*.
%
%      ICALIBRATESUBTRACT('CALLBACK',hObject,eventData,handles,...) calls the local
%      function named CALLBACK in ICALIBRATESUBTRACT.M with the given input arguments.
%
%      ICALIBRATESUBTRACT('Property','Value',...) creates a new ICALIBRATESUBTRACT or raises the
%      existing singleton*.  Starting from the left, property value pairs are
%      applied to the GUI before iCalibrateSubtract_OpeningFcn gets called.  An
%      unrecognized property name or invalid value makes property application
%      stop.  All inputs are passed to iCalibrateSubtract_OpeningFcn via varargin.
%
%      *See GUI Options on GUIDE's Tools menu.  Choose "GUI allows only one
%      instance to run (singleton)".
%
% See also: GUIDE, GUIDATA, GUIHANDLES

% Edit the above text to modify the response to help iCalibrateSubtract

% Last Modified by GUIDE v2.5 28-Oct-2012 17:01:10

% Begin initialization code - DO NOT EDIT
gui_Singleton = 1;
gui_State = struct('gui_Name',       mfilename, ...
                   'gui_Singleton',  gui_Singleton, ...
                   'gui_OpeningFcn', @iCalibrateSubtract_OpeningFcn, ...
                   'gui_OutputFcn',  @iCalibrateSubtract_OutputFcn, ...
                   'gui_LayoutFcn',  [] , ...
                   'gui_Callback',   []);
if nargin && ischar(varargin{1})
    gui_State.gui_Callback = str2func(varargin{1});
end

if nargout
    [varargout{1:nargout}] = gui_mainfcn(gui_State, varargin{:});
else
    gui_mainfcn(gui_State, varargin{:});
end
% End initialization code - DO NOT EDIT


% --- Executes just before iCalibrateSubtract is made visible.
function iCalibrateSubtract_OpeningFcn(hObject, eventdata, handles, varargin)
% This function has no output args, see OutputFcn.
% hObject    handle to figure
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
% varargin   command line arguments to iCalibrateSubtract (see VARARGIN)

% Choose default command line output for iCalibrateSubtract
handles.output = hObject;

% Update handles structure
guidata(hObject, handles);

% UIWAIT makes iCalibrateSubtract wait for user response (see UIRESUME)
% uiwait(handles.figure1);

% Choose default command line output for isub
handles.output = hObject;

% Update handles structure
guidata(hObject, handles);


global cr1;
global cr2;
global cg1;
global cg2;
global cb1;
global cb2;
global ch1;
global ch2;
global cs1;
global cs2;
global cv1;
global cv2;
global dthresh;
global nbwarea;
global nstremove;
global nstfill;


global inputsubtractfile;
global inputsubtractfilefull;

global outputfilesubtract;
global outputfilesubtractfull;

global outputfilesubtractbackup;
global outputfilesubtractbackupfull;

global backgroundsubtractfile;
global backgroundsubtractfilefull;

global ccbackup;

global bBackground;
global boutputfilesubtractedited;

boutputfilesubtractedited = 0;

ResetVariables(handles);

inputsubtractfile = '';
inputsubtractfilefull = '';

outputfilesubtract = '';
outputfilesubtractfull = '';

outputfilesubtractbackup = '';
outputfilesubtractbackupfull = '';

backgroundsubtractfile = '';
backgroundsubtractfilefull = '';

ccbackup = [];


SetValuesToDefault(handles)

savefile = 'videoprocessdata.mat';
load(savefile);


inputsubtractfile = inputfile;
inputsubtractfilefull = inputfilefull;

backgroundsubtractfile = backgroundfilefull;
backgroundsubtractfilefull = backgroundfilefull;

outputfilesubtract = calibsubtractfilefront;
outputfilesubtractfull = calibsubtractfilefrontfull;

if bFrontView == 0
    outputfilesubtract = calibsubtractfileside;
    outputfilesubtractfull = calibsubtractfilesidefull;
end


if isempty(outputfilesubtract)
    outputfilesubtractbackup = '';
end


if ~isempty(outputfilesubtractbackupfull)    
     scheckfile = dir(outputfilesubtractbackupfull);    
     if ~isempty(scheckfile)
        load(outputfilesubtractbackupfull);
        ccbackup = [cr1, cr2, cg1, cg2, cb1, cb2, ch1, ch2, cs1, cs2, cv1, cv2];   
     end   
end
    


if ~isempty(outputfilesubtractfull) 
     scheckfile = dir(outputfilesubtractfull);  
     
     if ~isempty(scheckfile)
        load(outputfilesubtractfull);    
     end                                
else        
    if ~isempty(inputsubtractfile)
        
        a = strfind(inputsubtractfile, '.');
        
        if ~isempty(a)
            outputfilesubtract = strcat(inputsubtractfile(1:a-1), '_subtract.mat');
            outputfilesubtractfull = strcat(pathname, outputfilesubtract);  
            
            
            scheckfile = dir(outputfilesubtractfull);  
     
            if ~isempty(scheckfile)
                load(outputfilesubtractfull);    
            end                       
    
            a = length(outputfilesubtract); 
            b = length(outputfilesubtractfull); 
    
            outputfilesubtractbackup = strcat(outputfilesubtract(1:a-4), '_backup.mat');
            outputfilesubtractbackupfull = strcat(outputfilesubtractfull(1:b-4), '_backup.mat');  
        end
    end
end


bBackground = 1;

if isempty(backgroundsubtractfilefull)
    bBackground = 0;
else
    scheck = dir(backgroundsubtractfilefull);
    
    if isempty(scheck)
        bBackground = 0;
    end
end


UpdateGUI(handles);    
UpdateEditBoxes(handles);    
UpdateImageVariables(handles);
UpdateImages(handles);

if bBackground == 1
    set(handles.editbackground, 'String', backgroundsubtractfilefull);
end
        



function ResetVariables(handles)

nframe = 1;
set(handles.editframe,'String', num2str(nframe));

nframediff = 50;
set(handles.editframediff,'String', num2str(nframediff));



function UpdateImageVariables(handles)

global inputsubtractfilefull;
global backgroundsubtractfilefull;

global img;
global dimg;
global img0;
global himg0;
global v;
global totalframes;

global bBackground;


bBackground = 0;

nframe = str2num(get(handles.editframe,'String'));
nframediff = str2num(get(handles.editframediff,'String'));

if nframe < 0 
    nframe = 1;
end


if ~isempty(inputsubtractfilefull)    
    scheckfile = dir(inputsubtractfilefull);

     if isempty(scheckfile)                   
        errordlg('Video file not found')  
        return
     else
        v = mmreader(inputsubtractfilefull); 
     end
else
    return
end

totalframes = v.NumberOfFrames;

if ~isempty(backgroundsubtractfilefull)    
    scheckfile = dir(backgroundsubtractfilefull);

     if isempty(scheckfile)                   
        %errordlg('Background file not found')  
        
        nframe2 = nframe + nframediff;
    
        if nframe2 > totalframes | nframe2 < 0
            nframe2 = totalframes;
        end
    
        img0 = read(v,nframe2);
     else
        load(backgroundsubtractfilefull)
        img0 = backgroundimg;
        bBackground = 1;
     end   
else
    nframe2 = nframe + nframediff;
    
    if nframe2 > totalframes | nframe2 < 0
        nframe2 = totalframes;
    end
    
    img0 = read(v,nframe2);
end


img = read(v,nframe);
himg0 = rgb2hsv(img0); 
dimg = double(img);





function UpdateFrames(handles)
global img;
global img0;

global dimg;
global himg0;

global v;
global totalframes;

global backgroundsubtractfilefull;
global inputsubtractfilefull;

global bBackground;

if isempty(inputsubtractfilefull) 
    return
end

nframe = str2num(get(handles.editframe,'String'));
nframediff = str2num(get(handles.editframediff,'String'));

if nframe < 0 
    nframe = 1;
end

nframe2 = nframe + nframediff;
    
if nframe2 > totalframes
    nframe2 = totalframes;
end

img = read(v,nframe);

if bBackground == 0
    img0 = read(v,nframe2);
    himg0 = rgb2hsv(img0); 
end

dimg = double(img);



function UpdateGUI(handles)

global cr1;
global cr2;
global cg1;
global cg2;
global cb1;
global cb2;
global ch1;
global ch2;
global cs1;
global cs2;
global cv1;
global cv2;
global dthresh;
global nbwarea;
global nstremove;
global nstfill;

set(handles.r1,'Min', 0.0);
set(handles.r1,'Max', 1.0);
set(handles.r1,'Value', cr1);
set(handles.textr1, 'String', num2str(cr1));

set(handles.r2,'Min', 1.0);
set(handles.r2,'Max', 2.0);
set(handles.r2,'Value', cr2);
set(handles.textr2, 'String', num2str(cr2));

set(handles.g1,'Min', 0.0);
set(handles.g1,'Max', 1.0);
set(handles.g1,'Value', cg1);
set(handles.textg1, 'String', num2str(cg1));

set(handles.g2,'Min', 1.0);
set(handles.g2,'Max', 2.0);
set(handles.g2,'Value', cg2);
set(handles.textg2, 'String', num2str(cg2));

set(handles.b1,'Min', 0.0);
set(handles.b1,'Max', 1.0);
set(handles.b1,'Value', cb1);
set(handles.textb1, 'String', num2str(cb1));

set(handles.b2,'Min', 1.0);
set(handles.b2,'Max', 2.0);
set(handles.b2,'Value', cb2);
set(handles.textb2, 'String', num2str(cb2));

set(handles.h1,'Min', 0.0);
set(handles.h1,'Max', 1.0);
set(handles.h1,'Value', ch1);
set(handles.texth1, 'String', num2str(ch1));

set(handles.h2,'Min', 1.0);
set(handles.h2,'Max', 2.0);
set(handles.h2,'Value', ch2);
set(handles.texth2, 'String', num2str(ch2));

set(handles.s1,'Min', 0.0);
set(handles.s1,'Max', 1.0);
set(handles.s1,'Value', cs1);
set(handles.texts1, 'String', num2str(cs1));

set(handles.s2,'Min', 1.0);
set(handles.s2,'Max', 2.0);
set(handles.s2,'Value', cs2);
set(handles.texts2, 'String', num2str(cs2));

set(handles.v1,'Min', 0.0);
set(handles.v1,'Max', 1.0);
set(handles.v1,'Value', cv1);
set(handles.textv1, 'String', num2str(cv1));

set(handles.v2,'Min', 1.0);
set(handles.v2,'Max', 2.0);
set(handles.v2,'Value', cv2);
set(handles.textv2, 'String', num2str(cv2));

set(handles.sliderthresh,'Min', 0.01);
set(handles.sliderthresh,'Max', 2.0);
set(handles.sliderthresh,'Value', dthresh);
set(handles.textthresh, 'String', num2str(dthresh));

set(handles.sliderbwarea,'Min', 0.0);
set(handles.sliderbwarea,'Max', 200.0);
set(handles.sliderbwarea,'Value', nbwarea);
set(handles.textbwarea, 'String', num2str(nbwarea));


set(handles.sliderstremove,'Min', 0.0);
set(handles.sliderstremove,'Max', 10.0);
set(handles.sliderstremove,'Value', nstremove);
set(handles.textstremove, 'String', num2str(nstremove));

set(handles.sliderstfill,'Min', 0.0);
set(handles.sliderstfill,'Max', 100.0);
set(handles.sliderstfill,'Value', nstfill);
set(handles.textstfill, 'String', num2str(nstfill));

set(handles.textoutput, 'String', '');


function UpdateImages(handles)


global cr1;
global cr2;
global cg1;
global cg2;
global cb1;
global cb2;
global ch1;
global ch2;
global cs1;
global cs2;
global cv1;
global cv2;

global img;
global dimg;
global img0;
global himg0;
global ccbackup;

global inputsubtractfile;
global inputsubtractfilefull;

global totalframes;

global bBackground;

global v;

if ~ishandle(handles.figure1)
    handles
    return;
end

if isempty(inputsubtractfilefull) 
    return
end


sinputsubtractfile = get(handles.editinput, 'String');

if inputsubtractfile ~= sinputsubtractfile & ~isempty(sinputsubtractfile)
    scheck = dir(sinputsubtractfile);
    
    if ~isempty(scheck)
        inputsubtractfile = sinputsubtractfile;
        inputsubtractfilefull = sinputsubtractfile;
        
        v = mmreader(inputsubtractfilefull);
        
        totalframes = v.NumberOfFrames;
        
        UpdateImageVariables(handles);
    end
end

cc = [cr1, cr2, cg1, cg2, cb1, cb2, ch1, ch2, cs1, cs2, cv1, cv2];

if isempty(ccbackup)
    ccbackup = cc;
end

axes(handles.axes1)
imshow(img);

axes(handles.axes2)
imshow(img0);


idiforg = dimg;
idiforg2 = dimg;
[im1, im2, im3] = SubtractImagesC(double(img0), idiforg, double(himg0), double(rgb2hsv(img)), ccbackup); 

idiforg(:,:,1) = im1;
idiforg(:,:,2) = im2;
idiforg(:,:,3) = im3;
idiforg = uint8(idiforg);

if bBackground == 0
    [im1, im2, im3] = SubtractImagesC(idiforg2, double(img0), double(himg0), double(rgb2hsv(img)), ccbackup); 

    idiforg2(:,:,1) = im1;
    idiforg2(:,:,2) = im2;
    idiforg2(:,:,3) = im3;
    idiforg = uint8(idiforg2) + idiforg;
end


cc = [cr1, cr2, cg1, cg2, cb1, cb2, ch1, ch2, cs1, cs2, cv1, cv2];

idif = dimg;
idif2 = dimg;
[im1, im2, im3] = SubtractImagesC(double(img0), idif, double(himg0), double(rgb2hsv(img)), cc); 

idif(:,:,1) = im1;
idif(:,:,2) = im2;
idif(:,:,3) = im3;
idif = uint8(idif);

if bBackground == 0
    [im1, im2, im3] = SubtractImagesC(idif2, double(img0), double(himg0), double(rgb2hsv(img)), cc); 

    idif2(:,:,1) = im1;
    idif2(:,:,2) = im2;
    idif2(:,:,3) = im3;
    idif = uint8(idif2)+idif;
end


axes(handles.axes4)
imshow(idiforg)

axes(handles.axes5)
imshow(idif)

bworg = BWImg(idiforg);
bw = BWImg(idif);


axes(handles.axes7)
imshow(bworg)

axes(handles.axes8)
imshow(bw)





function bw = BWImg(idif)

global dthresh;
global nbwarea;
global nstremove;
global nstfill;

seD = strel('diamond',nstremove);
idif = imerode(idif,seD);
I = rgb2gray(idif);
threshold = graythresh(I);
threshold = threshold*dthresh;
bw = im2bw(I,threshold);

%bw = CleanImage3(double(bw));
bw = bwareaopen(bw,nbwarea);
% fill a gap in the pen's cap
se = strel('diamond',nstfill);
bw = imclose(bw,se);
bw = imfill(bw,'holes');




%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%Functions called by event handlers
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%



function SliderR1Clicked(handles)
global cr1;

cr1 = get(handles.r1,'Value');
set(handles.textr1, 'String', num2str(cr1));

UpdateImages(handles)


function SliderR2Clicked(handles)
global cr2;

cr2 = get(handles.r2,'Value');
set(handles.textr2, 'String', num2str(cr2));

UpdateImages(handles)


function SliderG1Clicked(handles)
global cg1;

cg1 = get(handles.g1,'Value');
set(handles.textg1, 'String', num2str(cg1));

UpdateImages(handles)

function SliderG2Clicked(handles)
global cg2;

cg2 = get(handles.g2,'Value');
set(handles.textg2, 'String', num2str(cg2));

UpdateImages(handles)


function SliderB1Clicked(handles)
global cb1;


cb1 = get(handles.b1,'Value');
set(handles.textb1, 'String', num2str(cb1));

UpdateImages(handles)


function SliderB2Clicked(handles)
global cb2;

cb2 = get(handles.b2,'Value');
set(handles.textb2, 'String', num2str(cb2));

UpdateImages(handles)


function SliderH1Clicked(handles)
global ch1;

ch1 = get(handles.h1,'Value');
set(handles.texth1, 'String', num2str(ch1));

UpdateImages(handles)


function SliderH2Clicked(handles)
global ch2;

ch2 = get(handles.h2,'Value');
set(handles.texth2, 'String', num2str(ch2));
UpdateImages(handles)


function SliderS1Clicked(handles)
global cs1;

cs1 = get(handles.s1,'Value');
set(handles.texts1, 'String', num2str(cs1));

UpdateImages(handles)


function SliderS2Clicked(handles)
global cs2;

cs2 = get(handles.s2,'Value');
set(handles.texts2, 'String', num2str(cs2));

UpdateImages(handles)

function SliderV1Clicked(handles)
global cv1;

cv1 = get(handles.v1,'Value');
set(handles.textv1, 'String', num2str(cv1));

UpdateImages(handles)

function SliderV2Clicked(handles)
global cv2;

cv2 = get(handles.v2,'Value');
set(handles.textv2, 'String', num2str(cv2));


UpdateImages(handles)





function SliderThreshClicked(handles)
global dthresh;

dthresh = get(handles.sliderthresh,'Value');
set(handles.textthresh, 'String', num2str(dthresh));

UpdateImages(handles)

function SliderSTRemoveClicked(handles)
global nstremove;

nstremove = round(get(handles.sliderstremove,'Value'));
set(handles.textstremove, 'String', num2str(nstremove));

UpdateImages(handles)


function SliderBWAreaClicked(handles)
global nbwarea;

nbwarea = round(get(handles.sliderbwarea,'Value'));
set(handles.textbwarea, 'String', num2str(nbwarea));

UpdateImages(handles)


function SliderSTFill(handles)
global nstfill;

nstfill = round(get(handles.sliderstfill,'Value'));
set(handles.textstfill, 'String', num2str(nstfill));

UpdateImages(handles)






function SaveButtonClicked(handles)

global cr1;
global cr2;
global cg1;
global cg2;
global cb1;
global cb2;
global ch1;
global ch2;
global cs1;
global cs2;
global cv1;
global cv2;

global dthresh;
global nbwarea;
global nstremove;
global nstfill;

global outputfilesubtract;
global outputfilesubtractfull;
global outputfilesubtractbackup;
global outputfilesubtractbackupfull;

global boutputfilesubtractedited;

if isempty(outputfilesubtractfull) || boutputfilesubtractedited == 1
    outputfilesubtract = get(handles.editoutput, 'String');
    outputfilesubtractfull = get(handles.editoutput, 'String');
    
    if isempty(outputfilesubtractfull)
        errordlg('Please set Output File');
        return
    end
end

save(outputfilesubtractfull, 'cr1', 'cr2', 'cg1', 'cg2', 'cb1', 'cb2', 'ch1', 'ch2', 'cs1',...
               'cs2', 'cv1', 'cv2', 'dthresh', 'nbwarea', 'nstremove', 'nstfill');           

if isempty(outputfilesubtractbackupfull)
    a = length(outputfilesubtract); 
    b = length(outputfilesubtractfull); 
    
    outputfilesubtractbackup = strcat(outputfilesubtract(1:a-4), '_backup.mat');
    outputfilesubtractbackupfull = strcat(outputfilesubtractfull(1:b-4), '_backup.mat');                      
end

scheckfile = dir(outputfilesubtractbackupfull);
if isempty(scheckfile)
    save(outputfilesubtractbackupfull, 'cr1', 'cr2', 'cg1', 'cg2', 'cb1', 'cb2', 'ch1', 'ch2', 'cs1',...
               'cs2', 'cv1', 'cv2', 'dthresh', 'nbwarea', 'nstremove', 'nstfill');
end

set(handles.textoutput, 'String', 'File saved successfully');

           
function SaveBackupButtonClicked(handles)
global cr1;
global cr2;
global cg1;
global cg2;
global cb1;
global cb2;
global ch1;
global ch2;
global cs1;
global cs2;
global cv1;
global cv2;

global dthresh;
global nbwarea;
global nstremove;
global nstfill;

global outputfilesubtractfull;
global outputfilesubtractbackup;
global outputfilesubtractbackupfull;

if isempty(outputfilesubtractbackupfull) & isempty(outputfilesubtractfull)
    errordlg('Please set Output File');
    return
end
    
if isempty(outputfilesubtractbackupfull)
    a = length(outputfilesubtract); 
    b = length(outputfilesubtractfull); 
    
    outputfilesubtractbackup = strcat(outputfilesubtract(1:a-4), '_backup.mat');
    outputfilesubtractbackupfull = strcat(outputfilesubtractfull(1:b-4), '_backup.mat');                      
end


save(outputfilesubtractbackupfull, 'cr1', 'cr2', 'cg1', 'cg2', 'cb1', 'cb2', 'ch1', 'ch2', 'cs1',...
               'cs2', 'cv1', 'cv2', 'dthresh', 'nbwarea', 'nstremove', 'nstfill');

set(handles.textoutput, 'String', 'File saved successfully');


function ButtonGotoFrameClicked(handles)

%{
global img;
global dimg;
global v;
global totalframes;
global nframe;

sframe = get(handles.editframe,'String');
nframe = str2num(sframe);

if nframe >= 1 & nframe <= totalframes
    img = read(v,nframe);
    dimg = double(img);
end
%}

UpdateFrames(handles)
UpdateGUI(handles)
UpdateImages(handles)





function SetValuesToDefault(handles)

global cr1;
global cr2;
global cg1;
global cg2;
global cb1;
global cb2;
global ch1;
global ch2;
global cs1;
global cs2;
global cv1;
global cv2;
global dthresh;
global nbwarea;
global nstremove;
global nstfill;


cr1 = 0.5;
cr2 = 1.5;
cg1 = 0.5;
cg2 = 1.5;
cb1 = 0.5;
cb2 = 1.5;
ch1 = 1.0;
ch2 = 1.0;
cs1 = 1.0;
cs2 = 1.0;
cv1 = 1.0;
cv2 = 1.0;

dthresh = 0.5; 
nbwarea = 50; 
nstremove = 0; 
nstfill = 10; 

UpdateGUI(handles)
UpdateImages(handles)



function RestoreDefaultsButtonClicked(handles)
SetValuesToDefault(handles);
UpdateGUI(handles)



function EstimateButtonClicked(handles)

global cr1;
global cr2;
global cg1;
global cg2;
global cb1;
global cb2;
global ch1;
global ch2;
global cs1;
global cs2;
global cv1;
global cv2;
global dthresh;
global nbwarea;
global nstremove;
global nstfill;


global inputsubtractfilefull;

global v;

if isempty(inputsubtractfilefull) 
    return
end

nframes = 20;

totalframes = v.NumberOfFrames;

nstep = floor(totalframes/nframes);

img = read(v,1);   

%nx = 80;
%ny = 80;
%img = img(1:nx, 1:ny, :);

sz = size(img);

rs = zeros(sz(1), sz(2), nframes);
gs = zeros(sz(1), sz(2), nframes);
bs = zeros(sz(1), sz(2), nframes);

hs = zeros(sz(1), sz(2), nframes);
ss = zeros(sz(1), sz(2), nframes);
vs = zeros(sz(1), sz(2), nframes);

i = 1;
nframe = 1;


while i <= nframes & nframe <= totalframes    
    
    %i    
    img = read(v,nframe);
    himg = rgb2hsv(img);
        
    rs(:,:,i) = img(:,:,1);
    gs(:,:,i) = img(:,:,2);
    bs(:,:,i) = img(:,:,3);
    
    hs(:,:,i) = himg(:,:,1);
    ss(:,:,i) = himg(:,:,2);
    vs(:,:,i) = himg(:,:,3);
        
    nframe = nframe + nstep;
    i = i + 1;
end




k = 1.0;
dmax = 0.95;



rmean = mean(rs,3);
rstd = std(rs,0,3);
r = rstd./(rmean+1);


r = sort(r);
len = floor(length(r)*k);
r = mean(r(1:len));



gmean = mean(gs, 3);
gstd = std(gs,0,3);
g = gstd./(gmean+1);

g = sort(g);
len = floor(length(g)*k);
g = mean(g(1:len));


bmean = mean(bs, 3);
bstd = std(bs,0,3);
b = bstd./(bmean+1);

b = sort(b);
len = floor(length(b)*k);
b = mean(b(1:len));


hmean = mean(hs, 3);
hstd = std(hs,0,3);
h = hstd./(hmean+1);

h = sort(h);
len = floor(length(h)*k);
h = mean(h(1:len));


smean = mean(ss, 3);
sstd = std(ss,0,3);
s = sstd./(smean+1);

s = sort(s);
len = floor(length(s)*k);
s = mean(s(1:len));


vmean = mean(vs, 3);
vstd = std(vs,0,3);
vv = vstd./(vmean+1);

vv = sort(vv);
len = floor(length(vv)*k);
vv = mean(vv(1:len));

%[r, g, b, h, s, vv]

m = mean([r, g, b, h, s, vv]);


c = (0.5/m)-1;

c

dr = r*c;
dg = g*c;
db = b*c;
dh = h*c;
ds = s*c;
dv = vv*c;


[dr, dg, db, dh, ds, dv]

c = 1;

%c = 4;
dr = r*c;
dg = g*c;
db = b*c;
dh = h*c;
ds = s*c;
dv = vv*c;

[dr, dg, db, dh, ds, dv]

if dr > dmax
    dr = dmax;
end

if dg > dmax
    dg = dmax;
end

if db > dmax
    db = dmax;
end

if dh > dmax
    dh = dmax;
end

if ds > dmax
    ds = dmax;
end

if dv > dmax
    dv = dmax;
end

%{

cr1 = 1-dr;
cr2 = 1+dr;
cg1 = 1-dg;
cg2 = 1+dg;
cb1 = 1-db;
cb2 = 1+db;
%}

%{
ch1 = 1-dh;
ch2 = 1+dh;
cs1 = 1-ds;
cs2 = 1+ds;
cv1 = 1-dv;
cv2 = 1+dv;
%}


UpdateGUI(handles)
UpdateImages(handles)


function RestoreBackupButtonClicked(handles)
global ccbackup;
global outputfilesubtractbackupfull;

global outputfilesubtract;

if isempty(outputfilesubtractbackupfull)
    len = length(outputfilesubtract);
    outputfilesubtractbackupfull = strcat(outputfilesubtract(1:len-4), '_backup.mat');
end

if isempty(outputfilesubtractbackupfull)
    return;
end

scheckfile = dir(outputfilesubtractbackupfull);

if ~isempty(scheckfile)
    load(outputfilesubtractbackupfull);
    ccbackup = [cr1, cr2, cg1, cg2, cb1, cb2, ch1, ch2, cs1, cs2, cv1, cv2];
    
    UpdateGUI(handles)
    UpdateImages(handles)
else
    errordlg('Backup file not found');
end



function SliderGotoFrame(handles)


global totalframes;


n = get(handles.sliderframe, 'Value');
nframe = floor(totalframes*n)+1;

if nframe > totalframes
    nframe = totalframes;
end

if nframe >= 1 & nframe <= totalframes
    set(handles.editframe,'String', num2str(nframe));
end


UpdateFrames(handles)
UpdateGUI(handles)
UpdateImages(handles)







%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%Event handlers
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%


% --- Outputs from this function are returned to the command line.
function varargout = iCalibrateSubtract_OutputFcn(hObject, eventdata, handles) 
% varargout  cell array for returning output args (see VARARGOUT);
% hObject    handle to figure
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Get default command line output from handles structure
varargout{1} = handles.output;


% --- Executes on slider movement.
function r1_Callback(hObject, eventdata, handles)
% hObject    handle to r1 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hints: get(hObject,'Value') returns position of slider
%        get(hObject,'Min') and get(hObject,'Max') to determine range of slider

SliderR1Clicked(handles)


% --- Executes during object creation, after setting all properties.
function r1_CreateFcn(hObject, eventdata, handles)
% hObject    handle to r1 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

% Hint: slider controls usually have a light gray background.
if isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor',[.9 .9 .9]);
end


% --- Executes on slider movement.
function r2_Callback(hObject, eventdata, handles)
% hObject    handle to r2 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hints: get(hObject,'Value') returns position of slider
%        get(hObject,'Min') and get(hObject,'Max') to determine range of slider


SliderR2Clicked(handles)

% --- Executes during object creation, after setting all properties.
function r2_CreateFcn(hObject, eventdata, handles)
% hObject    handle to r2 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

% Hint: slider controls usually have a light gray background.
if isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor',[.9 .9 .9]);
end




% --- Executes on slider movement.
function g1_Callback(hObject, eventdata, handles)
% hObject    handle to g1 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hints: get(hObject,'Value') returns position of slider
%        get(hObject,'Min') and get(hObject,'Max') to determine range of slider

SliderG1Clicked(handles)



% --- Executes during object creation, after setting all properties.
function g1_CreateFcn(hObject, eventdata, handles)
% hObject    handle to g1 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

% Hint: slider controls usually have a light gray background.
if isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor',[.9 .9 .9]);
end



% --- Executes on slider movement.
function g2_Callback(hObject, eventdata, handles)
% hObject    handle to g2 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hints: get(hObject,'Value') returns position of slider
%        get(hObject,'Min') and get(hObject,'Max') to determine range of slider


SliderG2Clicked(handles)


% --- Executes during object creation, after setting all properties.
function g2_CreateFcn(hObject, eventdata, handles)
% hObject    handle to g2 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

% Hint: slider controls usually have a light gray background.
if isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor',[.9 .9 .9]);
end






% --- Executes on slider movement.
function b1_Callback(hObject, eventdata, handles)
% hObject    handle to b1 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hints: get(hObject,'Value') returns position of slider
%        get(hObject,'Min') and get(hObject,'Max') to determine range of slider

SliderB1Clicked(handles)


% --- Executes during object creation, after setting all properties.
function b1_CreateFcn(hObject, eventdata, handles)
% hObject    handle to b1 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

% Hint: slider controls usually have a light gray background.
if isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor',[.9 .9 .9]);
end


% --- Executes on slider movement.
function b2_Callback(hObject, eventdata, handles)
% hObject    handle to b2 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hints: get(hObject,'Value') returns position of slider
%        get(hObject,'Min') and get(hObject,'Max') to determine range of slider

SliderB2Clicked(handles)





% --- Executes during object creation, after setting all properties.
function b2_CreateFcn(hObject, eventdata, handles)
% hObject    handle to b2 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

% Hint: slider controls usually have a light gray background.
if isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor',[.9 .9 .9]);
end


% --- Executes on slider movement.
function h1_Callback(hObject, eventdata, handles)
% hObject    handle to h1 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hints: get(hObject,'Value') returns position of slider
%        get(hObject,'Min') and get(hObject,'Max') to determine range of slider


SliderH1Clicked(handles)




% --- Executes during object creation, after setting all properties.
function h1_CreateFcn(hObject, eventdata, handles)
% hObject    handle to h1 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

% Hint: slider controls usually have a light gray background.
if isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor',[.9 .9 .9]);
end





% --- Executes on slider movement.
function h2_Callback(hObject, eventdata, handles)
% hObject    handle to h2 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hints: get(hObject,'Value') returns position of slider
%        get(hObject,'Min') and get(hObject,'Max') to determine range of slider

SliderH2Clicked(handles)


% --- Executes during object creation, after setting all properties.
function h2_CreateFcn(hObject, eventdata, handles)
% hObject    handle to h2 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

% Hint: slider controls usually have a light gray background.
if isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor',[.9 .9 .9]);
end





% --- Executes on slider movement.
function s1_Callback(hObject, eventdata, handles)
% hObject    handle to s1 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hints: get(hObject,'Value') returns position of slider
%        get(hObject,'Min') and get(hObject,'Max') to determine range of slider

SliderS1Clicked(handles)



% --- Executes during object creation, after setting all properties.
function s1_CreateFcn(hObject, eventdata, handles)
% hObject    handle to s1 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

% Hint: slider controls usually have a light gray background.
if isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor',[.9 .9 .9]);
end


% --- Executes on slider movement.
function s2_Callback(hObject, eventdata, handles)
% hObject    handle to s2 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hints: get(hObject,'Value') returns position of slider
%        get(hObject,'Min') and get(hObject,'Max') to determine range of slider

SliderS2Clicked(handles)


% --- Executes during object creation, after setting all properties.
function s2_CreateFcn(hObject, eventdata, handles)
% hObject    handle to s2 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

% Hint: slider controls usually have a light gray background.
if isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor',[.9 .9 .9]);
end


% --- Executes on slider movement.
function v1_Callback(hObject, eventdata, handles)
% hObject    handle to v1 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hints: get(hObject,'Value') returns position of slider
%        get(hObject,'Min') and get(hObject,'Max') to determine range of slider

SliderV1Clicked(handles)

% --- Executes during object creation, after setting all properties.
function v1_CreateFcn(hObject, eventdata, handles)
% hObject    handle to v1 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

% Hint: slider controls usually have a light gray background.
if isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor',[.9 .9 .9]);
end


% --- Executes on slider movement.
function v2_Callback(hObject, eventdata, handles)
% hObject    handle to v2 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hints: get(hObject,'Value') returns position of slider
%        get(hObject,'Min') and get(hObject,'Max') to determine range of slider

SliderV2Clicked(handles)


% --- Executes during object creation, after setting all properties.
function v2_CreateFcn(hObject, eventdata, handles)
% hObject    handle to v2 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

% Hint: slider controls usually have a light gray background.
if isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor',[.9 .9 .9]);
end


% --- If Enable == 'on', executes on mouse press in 5 pixel border.
% --- Otherwise, executes on mouse press in 5 pixel border or over r1.
function r1_ButtonDownFcn(hObject, eventdata, handles)
% hObject    handle to r1 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)


% --- Executes on button press in savebutton.
function savebutton_Callback(hObject, eventdata, handles)
% hObject    handle to savebutton (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
SaveButtonClicked(handles)

% --- Executes on button press in pushbuttonrestore.
function pushbuttonrestore_Callback(hObject, eventdata, handles)
% hObject    handle to pushbuttonrestore (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

RestoreDefaultsButtonClicked(handles)



function editframe_Callback(hObject, eventdata, handles)
% hObject    handle to editframe (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hints: get(hObject,'String') returns contents of editframe as text
%        str2double(get(hObject,'String')) returns contents of editframe as a double


% --- Executes during object creation, after setting all properties.
function editframe_CreateFcn(hObject, eventdata, handles)
% hObject    handle to editframe (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

% Hint: edit controls usually have a white background on Windows.
%       See ISPC and COMPUTER.
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end


% --- Executes on button press in pushbuttonframe.
function pushbuttonframe_Callback(hObject, eventdata, handles)
% hObject    handle to pushbuttonframe (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

ButtonGotoFrameClicked(handles)




% --- Executes on slider movement.
function sliderthresh_Callback(hObject, eventdata, handles)
% hObject    handle to sliderthresh (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hints: get(hObject,'Value') returns position of slider
%        get(hObject,'Min') and get(hObject,'Max') to determine range of slider

SliderThreshClicked(handles)


% --- Executes during object creation, after setting all properties.
function sliderthresh_CreateFcn(hObject, eventdata, handles)
% hObject    handle to sliderthresh (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

% Hint: slider controls usually have a light gray background.
if isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor',[.9 .9 .9]);
end



% --- Executes on slider movement.
function sliderbwarea_Callback(hObject, eventdata, handles)
% hObject    handle to sliderbwarea (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hints: get(hObject,'Value') returns position of slider
%        get(hObject,'Min') and get(hObject,'Max') to determine range of slider

SliderBWAreaClicked(handles)


% --- Executes during object creation, after setting all properties.
function sliderbwarea_CreateFcn(hObject, eventdata, handles)
% hObject    handle to sliderbwarea (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

% Hint: slider controls usually have a light gray background.
if isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor',[.9 .9 .9]);
end


% --- Executes on slider movement.
function sliderstremove_Callback(hObject, eventdata, handles)
% hObject    handle to sliderstremove (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hints: get(hObject,'Value') returns position of slider
%        get(hObject,'Min') and get(hObject,'Max') to determine range of slider

SliderSTRemoveClicked(handles)



% --- Executes during object creation, after setting all properties.
function sliderstremove_CreateFcn(hObject, eventdata, handles)
% hObject    handle to sliderstremove (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

% Hint: slider controls usually have a light gray background.
if isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor',[.9 .9 .9]);
end


% --- Executes on slider movement.
function sliderstfill_Callback(hObject, eventdata, handles)
% hObject    handle to sliderstfill (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hints: get(hObject,'Value') returns position of slider
%        get(hObject,'Min') and get(hObject,'Max') to determine range of slider

SliderSTFill(handles)



% --- Executes during object creation, after setting all properties.
function sliderstfill_CreateFcn(hObject, eventdata, handles)
% hObject    handle to sliderstfill (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

% Hint: slider controls usually have a light gray background.
if isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor',[.9 .9 .9]);
end

% --- Executes during object creation, after setting all properties.
function editfile_CreateFcn(hObject, eventdata, handles)
% hObject    handle to editfile (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

% Hint: edit controls usually have a white background on Windows.
%       See ISPC and COMPUTER.
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end




% --- Executes on slider movement.
function sliderframe_Callback(hObject, eventdata, handles)
% hObject    handle to sliderframe (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hints: get(hObject,'Value') returns position of slider
%        get(hObject,'Min') and get(hObject,'Max') to determine range of slider

SliderGotoFrame(handles)



% --- Executes during object creation, after setting all properties.
function sliderframe_CreateFcn(hObject, eventdata, handles)
% hObject    handle to sliderframe (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

% Hint: slider controls usually have a light gray background.
if isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor',[.9 .9 .9]);
end


% --- Executes on button press in pushbutton6.
function pushbutton6_Callback(hObject, eventdata, handles)
% hObject    handle to pushbutton6 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

close()



function editinput_Callback(hObject, eventdata, handles)
% hObject    handle to editinput (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hints: get(hObject,'String') returns contents of editinput as text
%        str2double(get(hObject,'String')) returns contents of editinput as a double


% --- Executes during object creation, after setting all properties.
function editinput_CreateFcn(hObject, eventdata, handles)
% hObject    handle to editinput (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

% Hint: edit controls usually have a white background on Windows.
%       See ISPC and COMPUTER.
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end



function editoutput_Callback(hObject, eventdata, handles)
% hObject    handle to editoutput (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hints: get(hObject,'String') returns contents of editoutput as text
%        str2double(get(hObject,'String')) returns contents of editoutput as a double


% --- Executes during object creation, after setting all properties.
function editoutput_CreateFcn(hObject, eventdata, handles)
% hObject    handle to editoutput (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

% Hint: edit controls usually have a white background on Windows.
%       See ISPC and COMPUTER.
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end


% --- Executes on button press in pushbuttoninput.
function pushbuttoninput_Callback(hObject, eventdata, handles)
% hObject    handle to pushbuttoninput (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

global inputsubtractfile;
global inputsubtractfilefull;

global outputfilesubtract;
global outputfilesubtractfull;

global outputfilesubtractbackup;
global outputfilesubtractbackupfull;

global backgroundsubtractfile;
global backgroundsubtractfilefull;

global ccbackup;

[filename, pathname] = uigetfile( ...
{'*.avi; *.mpg; *.mpeg','Video Files (*.avi, *.mpg, *.mpeg)';   
 '*.*',  'All Files (*.*)'}, ...
 'Pick a file');

if filename ~= 0
    
    set(handles.textoutput, 'String', 'Loading...');
    
    inputsubtractfile = filename;
    inputsubtractfilefull = strcat(pathname, filename);    
    
    a = strfind(filename, '.');
    
    if ~isempty(a)
        
        %update output file name
        outputfilesubtract = strcat(filename(1:a-1), '_subtract.mat');
        outputfilesubtractfull = strcat(pathname, outputfilesubtract);           
        
        outputfilesubtractbackup = strcat(filename(1:a-1), 'subtract_backup.mat');
        outputfilesubtractbackupfull = strcat(pathname, outputfilesubtract); 
        
        backgroundsubtractfile = strcat(filename(1:a-1), '_background.mat');
        backgroundsubtractfilefull = strcat(pathname, backgroundsubtractfile);           
        
        ccbackup = [];
         
        scheckfile = dir(outputfilesubtractbackupfull);    
        if ~isempty(scheckfile)
            load(outputfilesubtractbackupfull);
            ccbackup = [cr1, cr2, cg1, cg2, cb1, cb2, ch1, ch2, cs1, cs2, cv1, cv2];
        else
            outputfilesubtractbackup = '';
            outputfilesubtractbackupfull = '';
        end   
    
        scheckfile = dir(outputfilesubtractfull);    
        if ~isempty(scheckfile)
            load(outputfilesubtractfull);
        else
            outputfilesubtract = '';
            outputfilesubtractfull = '';
        end          
                
        scheckfile = dir(backgroundsubtractfilefull);    
        if ~isempty(scheckfile)
            %load(backgroundsubtractfilefilefull);
        else
            backgroundsubtractfile = '';
            backgroundsubtractfilefull = '';
        end         

        ResetVariables(handles);
        
        UpdateGUI(handles);    
        UpdateEditBoxes(handles);    
        UpdateImageVariables(handles);
        UpdateImages(handles);
    end        
    
    set(handles.textoutput, 'String', '');
end



% --- Executes on button press in pushbuttonoutput.
function pushbuttonoutput_Callback(hObject, eventdata, handles)
% hObject    handle to pushbuttonoutput (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)


%These variables are updated when outputfilesubtract loaded
global cr1;
global cr2;
global cg1;
global cg2;
global cb1;
global cb2;
global ch1;
global ch2;
global cs1;
global cs2;
global cv1;
global cv2;
global dthresh;
global nbwarea;
global nstremove;
global nstfill;

global ccbackup;

global outputfilesubtract;
global outputfilesubtractfull;

global outputfilesubtractbackup;
global outputfilesubtractbackupfull;

global backgroundsubtractfile;
global backgroundsubtractfilefull;

[filename, pathname] = uigetfile( ...
{'*.mat','Matlab Data Files (*.mat)';   
 '*.*',  'All Files (*.*)'}, ...
 'Pick a file');

if filename ~= 0
    outputfilesubtract = filename;
    outputfilesubtractfull = strcat(pathname, filename);
    
    a = length(filename);
    outputfilesubtractbackup = strcat(filename(1:a-4), '_backup.mat');
    outputfilesubtractbackupfull = strcat(pathname, outputfilesubtract);           
    
    
    scheckfile = dir(outputfilesubtractbackupfull);    
    if ~isempty(scheckfile)
        load(outputfilesubtractbackupfull);
        ccbackup = [cr1, cr2, cg1, cg2, cb1, cb2, ch1, ch2, cs1, cs2, cv1, cv2];
    end   
    
    scheckfile = dir(outputfilesubtractfull);    
    if ~isempty(scheckfile)
        load(outputfilesubtractfull);
    end    
 
    
    UpdateGUI(handles);    
    UpdateEditBoxes(handles);    
    UpdateImageVariables(handles);
    UpdateImages(handles);
end



function UpdateEditBoxes(handles)

global inputsubtractfile;
global outputfilesubtract;
global backgroundsubtractfile;

set(handles.editinput, 'String', inputsubtractfile);
set(handles.editoutput, 'String', outputfilesubtract);
set(handles.editbackground, 'String', backgroundsubtractfile);


function UpdateData(handles)

global inputsubtractfile;
global outputfilesubtract;
global backgroundsubtractfile;

global savefile;

load(savefile);

set(handles.editinput, 'String', inputsubtractfile);
set(handles.editoutput, 'String', outputfilesubtract);
set(handles.editbackground, 'String', backgroundsubtractfile);


function editbackground_Callback(hObject, eventdata, handles)
% hObject    handle to editbackground (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hints: get(hObject,'String') returns contents of editbackground as text
%        str2double(get(hObject,'String')) returns contents of editbackground as a double


% --- Executes during object creation, after setting all properties.
function editbackground_CreateFcn(hObject, eventdata, handles)
% hObject    handle to editbackground (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

% Hint: edit controls usually have a white background on Windows.
%       See ISPC and COMPUTER.
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end


% --- Executes on button press in pushbuttonbackground.
function pushbuttonbackground_Callback(hObject, eventdata, handles)
% hObject    handle to pushbuttonbackground (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

global backgroundsubtractfile;
global backgroundsubtractfilefull;

global bBackground;

[filename, pathname] = uigetfile( ...
{'*.mat','Matlab Data Files (*.mat)';   
 '*.*',  'All Files (*.*)'}, ...
 'Pick a file');

if filename ~= 0
    backgroundsubtractfile = filename;
    backgroundsubtractfilefull = strcat(pathname, filename);
            
    set(handles.textoutput, 'String', 'Loading...');
    
    UpdateEditBoxes(handles);
    UpdateImageVariables(handles);
    
    UpdateImages(handles);
    
    set(handles.textoutput, 'String', '');
    

    bBackground = 1;
    scheck = dir(backgroundsubtractfilefull);
    
    if isempty(scheck)
        bBackground = 0;
    end
end




% --- Executes on button press in pushbuttonrestorebackup.
function pushbuttonrestorebackup_Callback(hObject, eventdata, handles)
% hObject    handle to pushbuttonrestorebackup (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

RestoreBackupButtonClicked(handles);

% --- Executes on button press in pushbuttonsavebackup.
function pushbuttonsavebackup_Callback(hObject, eventdata, handles)
% hObject    handle to pushbuttonsavebackup (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

SaveBackupButtonClicked(handles);

function editframediff_Callback(hObject, eventdata, handles)
% hObject    handle to editframediff (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hints: get(hObject,'String') returns contents of editframediff as text
%        str2double(get(hObject,'String')) returns contents of editframediff as a double


% --- Executes during object creation, after setting all properties.
function editframediff_CreateFcn(hObject, eventdata, handles)
% hObject    handle to editframediff (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

% Hint: edit controls usually have a white background on Windows.
%       See ISPC and COMPUTER.
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
    set(hObject,'BackgroundColor','white');
end


% --- Executes on button press in pushbuttonupdate.
function pushbuttonupdate_Callback(hObject, eventdata, handles)
% hObject    handle to pushbuttonupdate (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

UpdateFrames(handles);
UpdateImages(handles);


% --- Executes on button press in pushbuttonupdateimages.
function pushbuttonupdateimages_Callback(hObject, eventdata, handles)
% hObject    handle to pushbuttonupdateimages (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

UpdateImages(handles);


% --- Executes on button press in pushbuttonestimate.
function pushbuttonestimate_Callback(hObject, eventdata, handles)
% hObject    handle to pushbuttonestimate (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

set(handles.textoutput, 'String', 'Estimating...');
EstimateButtonClicked(handles)
set(handles.textoutput, 'String', '');



% --- Executes on key press with focus on editoutput and none of its controls.
function editoutput_KeyPressFcn(hObject, eventdata, handles)
% hObject    handle to editoutput (see GCBO)
% eventdata  structure with the following fields (see UICONTROL)
%	Key: name of the key that was pressed, in lower case
%	Character: character interpretation of the key(s) that was pressed
%	Modifier: name(s) of the modifier key(s) (i.e., control, shift) pressed
% handles    structure with handles and user data (see GUIDATA)


global boutputfilesubtractedited;

boutputfilesubtractedited = 1;
